/*
Copyright 2010-2011 CumulusCloud
http://cumuluscloud.cc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package appmanager.server.appstore.runner;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

public abstract class Downloader implements Runnable {
	private static Logger logger = Logger.getLogger(Downloader.class.getName());
	private long progress;
	protected long end = -1;
	protected String status = "";
	
	protected boolean downloadUrl(List<String> urls, File file, int retries) {
		Collections.shuffle(urls);
		
		int retry = retries;
		boolean success = false;
		// Retries loop
		do {
			// Wait before retrying
			if (retry != retries) {
				logger.info("Will retry download in 30 seconds");
				try {
					Thread.sleep(30000);
				} catch (InterruptedException e) {
				}
			}
			
			// Next url loop
			for (String theUrl : urls) {
				// Download the file
				logger.info("Downloading file " + urls);
				success = downloadUrl(theUrl, file);
				if (success) {
					break;
				}
			}
			
			--retry;
		} while (!success && (retry > 0));
		
		return success;
	}
	
	protected boolean downloadUrl(String theUrl, File file) {
		logger.info("Starting downloading " + theUrl);
		progress = 0;
		URL url;
		try {
			url = new URL(theUrl);
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return false;
		}

		InputStream in = null;
		OutputStream out = null;
		try {
			in = url.openStream();
			out = new FileOutputStream(file);
			
			int len;
			byte[] b = new byte[1024];
			while ( (len = in.read(b)) > 0) {
				progress += len;
				out.write(b, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (NullPointerException e) {
			}
		}
		
		return true;
	}
	
	protected boolean downloadUrl(String theUrl, File file, int retries) {
		int retry = retries;
		boolean success;
		do {
			// Wait before retrying
			if (retry != retries) {
				logger.info("Will retry download in 30 seconds");
				try {
					Thread.sleep(30000);
				} catch (InterruptedException e) {
				}
			}
			
			// Download the file
			logger.info("Downloading file");
			success = downloadUrl(theUrl, file);
			--retry;
		} while (!success && (retry > 0));
		
		return success;
	}
	
	public long getEnd() {
		return end;
	}
	
	public abstract String getName();
	
	public long getProgress() {
		return progress;
	}
	
	public String getStatus() {
		return status;
	}
	
	public void setFinalStatus(String status) {
		this.status = status;
		end = new Date().getTime();
	}
	
	public void setStatus(String status) {
		this.status = status;
	}
}
